home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / cmdity / yk212src.lha / Yak_2.12_Src / handlers.c < prev    next >
C/C++ Source or Header  |  1996-03-03  |  26KB  |  935 lines

  1. /*
  2.  * Handlers.c
  3.  *
  4.  * This module contains the input handlers set up by Yak.
  5.  * 
  6.  * The main handler is for autopointing, keyactivation, keyclicking and blanking
  7.  * There's are 3 specialized handlers for mouse cycling functions : WindowToFront,
  8.  * WindowToBack, and ScreenCycling.
  9.  * 
  10.  */
  11.  
  12. #define __USE_SYSBASE
  13.  
  14. #include <exec/types.h>
  15. #include <exec/exec.h>
  16. #include <devices/console.h>
  17. #include <devices/input.h>
  18. #include <devices/inputevent.h>
  19. #include <libraries/commodities.h>
  20. #include <graphics/gfx.h>
  21. #include <graphics/gfxbase.h>
  22. #include <graphics/gfxmacros.h>
  23. #include <graphics/displayinfo.h>
  24. #include <hardware/custom.h>
  25. #include <hardware/dmabits.h>
  26. #include <intuition/intuition.h>
  27. #include <intuition/intuitionbase.h>
  28. #include <proto/exec.h>
  29. #include <proto/dos.h>
  30. #include <proto/layers.h>
  31. #include <proto/graphics.h>
  32. #include <proto/intuition.h>
  33. #include <proto/commodities.h>
  34. #include <ctype.h>
  35. #include <string.h>
  36. #include <stdio.h>
  37.  
  38. #include "code.h"
  39. #include "yak.h"
  40. #include "Settings.h"
  41. #include "Handlers.h"
  42. #include "hotkey_types.h"
  43. #ifdef PREFS
  44. #  define CATCOMP_NUMBERS
  45. #  include "yak_locale_strings.h"
  46. #  include "Requesters.h"
  47. #else
  48. #  ifndef CONV
  49. #    include "Beep.h"
  50. #    include "LastActiveWindow.h"
  51. #    include "CapShift.h"
  52. #    include "Blankers.h"
  53. #  endif
  54. #endif
  55.  
  56.  
  57. static char ExcludeWbWindowPattern[20]; /* Normally it takes 13 bytes but it doesn't hurt to
  58.                                          * take more in case pattern representation change
  59.                                          */
  60.  
  61.  
  62. YakHandler MouseCyclingHandlers[NUM_HANDLERS] = {
  63. { NULL, NULL, 0, 0, 0, 0, NULL, "", NULL},
  64. { NULL, NULL, 0, 0, 0, 0, NULL, "", NULL},
  65. { NULL, NULL, 0, 0, 0, 0, NULL, "", NULL}
  66. };
  67.  
  68. YakHandler DEF_MOUSECYCLING[NUM_HANDLERS]= {
  69. { NULL, WindowToFrontHandler, YKHK_INACTIVE, WINDOW_TOFRONT_EVENT, DEF_TOFRONT_CLICKS      , DEF_TOFRONT_OPTIONS      , DEF_TOFRONT_HOTKEY      , DEF_SCREENPATTERN },
  70. { NULL, WindowToBackHandler , YKHK_INACTIVE, WINDOW_TOBACK_EVENT,  DEF_TOBACK_CLICKS       , DEF_TOBACK_OPTIONS       , DEF_TOBACK_HOTKEY       , DEF_SCREENPATTERN },
  71. { NULL, ScreenCyclingHandler, YKHK_INACTIVE, SCREENCYCLING_EVENT,  DEF_SCREENCYCLING_CLICKS, DEF_SCREENCYCLING_OPTIONS, DEF_SCREENCYCLING_HOTKEY, DEF_SCREENPATTERN }
  72. };
  73.  
  74.  
  75. VOID
  76.    CleanMouseCycling(void)
  77. {
  78.    register int i;
  79.    
  80.    for (i=0; i<NUM_HANDLERS; i++)
  81.    {
  82.       if (MouseCyclingHandlers[i].ScreenPatternData.pat)
  83.       { 
  84.          FreeVec(MouseCyclingHandlers[i].ScreenPatternData.pat);
  85.          MouseCyclingHandlers[i].ScreenPatternData.pat=NULL;
  86.       }
  87.       
  88.       if (MouseCyclingHandlers[i].KeyDef)
  89.       { 
  90.          FreeVec(MouseCyclingHandlers[i].KeyDef);
  91.          MouseCyclingHandlers[i].KeyDef=NULL;
  92.       }
  93.       
  94.       /* DeleteCxObjAll() works even with NULL argument */
  95.       DeleteCxObjAll(MouseCyclingHandlers[i].CxObj);    
  96.       MouseCyclingHandlers[i].CxObj=NULL;
  97.    }
  98. }
  99.  
  100.  
  101.  
  102. VOID
  103.    InitMouseCyclingPatterns (VOID)
  104. {
  105.    UBYTE i;
  106.    
  107.    for (i=0; i<NUM_HANDLERS; i++)
  108.    {
  109.       InitPattern(MouseCyclingHandlers[i].ScreenPatternData.patstr,
  110.                   &MouseCyclingHandlers[i].ScreenPatternData);
  111.    }
  112.    
  113. #if !defined(PREFS) && !defined(CONV)
  114.    /* Initialize the pattern to exclude Wb window for Window_To_Front */
  115.    ParsePattern("~(Workbench)", ExcludeWbWindowPattern, 20);
  116. #endif    
  117. }
  118.  
  119.  
  120. /*
  121.  *  CompatibleParseIX - frontend to ParseIX() to allow compatibility of V38+ 
  122.  *  commodity.library hotkey definitions with V37 library.
  123.  */
  124.  
  125. long 
  126.    CompatibleParseIX(char *I_Description, IX *ix)
  127. {
  128.    char *pos=NULL;
  129.    UBYTE c, begin;
  130.    long failurecode = 0l;
  131.    UWORD code = 0;
  132.    char *description;
  133.    
  134.    if (I_Description == NULL)
  135.    {
  136.       failurecode = -2;
  137.    }
  138.    else
  139.    {
  140.       /* Skip blank spaces in a 68000 compatible way, avoid odd addresses */
  141.       
  142.       begin = 0;
  143.       while (I_Description[begin] == ' ') 
  144.       {
  145.          begin++;
  146.       }
  147.       
  148.       if (CxBase->lib_Version < 38L) /* COMMODITIES_V37 */
  149.       {
  150.          description = AllocVec(strlen(I_Description)+1-begin, MEMF_CLEAR);
  151.          
  152.          for (c=begin; c<strlen(I_Description); c++)
  153.             description[c-begin] = tolower(I_Description[c]);
  154.          
  155.          /*
  156.           *  parse and remove keywords that are not supported
  157.           *  by V37 commodities.library
  158.           *
  159.           */
  160.          if (pos = strstr(description, " mouse_leftpress"))
  161.          {
  162.             code = IECODE_LBUTTON;
  163.          }
  164.          else 
  165.          {
  166.             if (pos = strstr(description, " mouse_rightpress"))
  167.             {
  168.                code = IECODE_RBUTTON;
  169.             }
  170.             else 
  171.             {
  172.                if (pos = strstr(description, " mouse_middlepress"))
  173.                {
  174.                   code = IECODE_MBUTTON;
  175.                }
  176.             }
  177.          }
  178.          
  179.          if (pos)                        /* RawMouse class */
  180.          {
  181.             /* Put an end to our description before unsupported keywords
  182.              * but avoid odd address for 68000 
  183.              */
  184.             description[(LONG)pos - (LONG)description]= '\0';
  185.          }
  186.          
  187.          failurecode = ParseIX((UBYTE *)description, ix);
  188.          
  189.          /*
  190.           *  now change ix for our new keywords
  191.           *
  192.           */
  193.          if (code) 
  194.          {
  195.             /*
  196.              *  change code
  197.              *
  198.              */
  199.             if (ix->ix_Class != IECLASS_RAWMOUSE)
  200.                failurecode = -1;
  201.             else
  202.                ix->ix_Code = code;
  203.             
  204.             /*
  205.              *  change also QualMask for mouse buttons
  206.              *
  207.              */
  208.             ix->ix_QualMask |= IEQUALIFIER_MIDBUTTON | IEQUALIFIER_RBUTTON | IEQUALIFIER_LEFTBUTTON;
  209.             
  210.             /*
  211.              *  parse for qualifiers the use wants to be considered irrelevant
  212.              *
  213.              */
  214.             if (strstr(description, "-leftbutton")) ix->ix_QualMask &= ~IEQUALIFIER_LEFTBUTTON;
  215.             if (strstr(description, "-midbutton")) ix->ix_QualMask &= ~IEQUALIFIER_MIDBUTTON;
  216.             if (strstr(description, "-rbutton")) ix->ix_QualMask &= ~IEQUALIFIER_RBUTTON;
  217.             
  218.          }
  219.          
  220.          FreeVec(description);
  221.       }
  222.       else                                    /* COMMODITIES_V38+ */
  223.       {
  224.          /* Use the definition as is */
  225.          failurecode = ParseIX((UBYTE *)I_Description, ix);
  226.       }
  227.       
  228.       if (!failurecode)
  229.       {
  230.          /* Patch ParseIX() up */
  231.          if (ix->ix_Class == IECLASS_RAWMOUSE)
  232.          {
  233.             if (ix->ix_Code == IECODE_LBUTTON) ix->ix_Qualifier |= IEQUALIFIER_LEFTBUTTON;
  234.             if (ix->ix_Code == IECODE_MBUTTON) ix->ix_Qualifier |= IEQUALIFIER_MIDBUTTON;
  235.             if (ix->ix_Code == IECODE_RBUTTON) ix->ix_Qualifier |= IEQUALIFIER_RBUTTON;
  236.          }
  237.          ix->ix_QualMask |= ix->ix_Qualifier;
  238.       }
  239.    }
  240.    return(failurecode);
  241. }
  242.  
  243. #if !defined(PREFS) && !defined(CONV)
  244.  
  245. static __regargs void IntuiOp (void (*routine) (APTR), APTR parameter);
  246. static __regargs void PopToFront (struct Window *win);
  247. static __regargs BOOL StrGadgetActive (struct Window *w);
  248.  
  249. void (*intui_routine) (APTR);   /* for intui_op's */
  250. APTR intui_parameter;
  251. CxObj *clickobj;
  252. ULONG clicksigflag, intuiopsigflag, blankscreensigflag, depthscreensigflag;
  253. static BYTE clicksigbit, blankscreensigbit, depthscreensigbit, intuiopsigbit = -1;
  254. static BOOL misspop;
  255.  
  256. /* for screen cycling */
  257. STACKARGS void
  258.    MyScreenToBack (struct Screen *scr)
  259. {
  260.    RememberActiveWindow(NULL);
  261.    ScreenToBack (scr);
  262.    ActivateMouseWindow (SCREEN);
  263. }
  264.  
  265. STACKARGS void
  266.    MyScreenToFront (struct Screen *scr)
  267. {
  268.    RememberActiveWindow(NULL);
  269.    ScreenToFront (scr);
  270.    ActivateMouseWindow (SCREEN);
  271. }
  272.  
  273.  
  274. /* Stub for Intuition routines - passes request on to main task.
  275.  * DO NOT CALL WHILE FORBID()ING!
  276.  * Thanks to Eddy Carroll for this.
  277.  */
  278.  
  279. #define WTB(win)        IntuiOp(WindowToBack, win)
  280. #define WTF(win)        IntuiOp(WindowToFront, win)
  281. #define WACT(win)       IntuiOp((void (*)(APTR))ActivateWindow, win)
  282. #define STB(scr)        IntuiOp(MyScreenToBack, scr)
  283. #define STF(scr)        IntuiOp(MyScreenToFront, scr)
  284.  
  285. BYTE oldpri;                  /* used by main.c */
  286. static struct Task *YakTask;  
  287.  
  288. static __regargs void
  289.    IntuiOp (void (*routine) (APTR), APTR parameter)
  290. {
  291.    oldpri  = SetTaskPri (YakTask, 21);
  292.    intui_routine = routine;
  293.    intui_parameter = parameter;
  294.    Signal (YakTask, intuiopsigflag);
  295.    SetTaskPri (YakTask, oldpri);
  296. }
  297.  
  298. /* pattern-matching on screen/window titles */
  299. #define IsXXXScreen(scr, pat)          (scr && (!scr->DefaultTitle || MatchPattern(pat, scr->DefaultTitle)))
  300. #define IsAutoScreen(scr)              IsXXXScreen(scr, autoscrpat)
  301. #define IsXXXWindow(win, pat)          (!win->Title || MatchPattern(pat, win->Title))
  302. #define IsPopWindow(win)               IsXXXWindow(win,popwinpat)
  303. #define IsNotWbWindow(win)             (!win->Title || MatchPattern(ExcludeWbWindowPattern, win->Title))
  304. #define IsIncludedScreen(scr,handler)  IsXXXScreen(scr, handler.ScreenPatternData.pat) 
  305.  
  306. /* when is a window safe to bring to front and not already at front? */
  307. #define OkayToPop(win)  (!win->ReqCount && !(win->Flags & (WFLG_MENUSTATE|WFLG_BACKDROP)) \
  308.                          && win->WLayer->ClipRect && win->WLayer->ClipRect->Next)
  309.  
  310.  
  311.  
  312. /* WindowToFront only if no requester, not backdrop, not already front... */
  313. static __regargs void
  314.    PopToFront (struct Window *win)
  315. {
  316.    /* want to avoid popping immediately after mousebutton/keyboard */
  317.    if (misspop)
  318.    {
  319.       misspop = FALSE;
  320.    }
  321.    else
  322.    { 
  323.       if (OkayToPop (win))
  324.       {
  325.          /* Does it pass pattern? */
  326.          if (IsPopWindow (win))
  327.          {
  328.             WTF (win); /* We use signals to reduce time spent in the input device */
  329.          }
  330.       }
  331.    }
  332. }
  333.  
  334. /* modified from DMouse */
  335. /* expects multitasking to be Forbid()en */
  336.  
  337. static struct Screen *mousescr; /* the screen under the mouse */
  338.  
  339.  
  340. struct Screen *
  341.    ScreenUnderMouse( void )
  342. {
  343.    struct Screen *scr;
  344.    ULONG lock;
  345.    
  346.    lock = LockIBase(0);
  347.    
  348.    for (scr = IntuitionBase->FirstScreen;
  349.         scr && scr->TopEdge > 0 && scr->MouseY < 0; 
  350.         scr = scr->NextScreen);
  351.    
  352.    UnlockIBase(lock);
  353.    
  354.    return(scr);
  355. }
  356.  
  357.  
  358. struct Window *
  359.    WindowUnderMouse( void )
  360. {
  361.    struct Layer *layer = NULL;
  362.    ULONG lock;
  363.    
  364.    lock = LockIBase(0);
  365.    
  366.    for (mousescr = IntuitionBase->FirstScreen;
  367.         mousescr && mousescr->TopEdge > 0 && mousescr->MouseY < 0; 
  368.         mousescr = mousescr->NextScreen);
  369.    
  370.    UnlockIBase(lock);
  371.    
  372.    if (mousescr)
  373.       layer = WhichLayer(&mousescr->LayerInfo, mousescr->MouseX, mousescr->MouseY);
  374.    
  375.    return (layer ? (struct Window *) layer->Window : NULL);
  376. }
  377.  
  378.  
  379. /* does active window have an active string gadget? */
  380. static __regargs BOOL
  381.    StrGadgetActive (struct Window *w)
  382. {
  383.    struct Gadget *g = w->FirstGadget;
  384.    
  385.    for (; g; g = g->NextGadget)
  386.       if ((g->GadgetType & STRGADGET) && (g->Flags & GFLG_SELECTED))
  387.          return TRUE;
  388.    return FALSE;
  389. }
  390.  
  391. /* activate window under mouse */
  392. /* context sensitive; why tells routine how to behave */
  393. /* can be AUTO, KEY, SCREEN, RMBACT */
  394. __regargs void
  395.    ActivateMouseWindow (BYTE why)
  396. {
  397.    struct Window *win = NULL, *IB_ActiveWindow;
  398.    ULONG lock;
  399.    
  400.    if ((why != SCREEN) || scractivate)
  401.    {
  402.       if (why == SCREEN)
  403.       {
  404.          win = LastActiveWindow(ScreenUnderMouse());
  405.       }
  406.       
  407.       if (!win)
  408.          win = WindowUnderMouse ();
  409.       
  410.       if (win)                /* window exists to activate */
  411.       {
  412.          /* either window is not active or auto-activating - need to pop? */
  413.          
  414.          if (win->Flags & WFLG_WINDOWACTIVE) /* already active - needs popped? */
  415.          {
  416.             if (why == AUTO && autopop && IsAutoScreen (win->WScreen))
  417.             {
  418.                PopToFront (win);
  419.             }
  420.          }
  421.          else if (why != AUTO || IsAutoScreen (win->WScreen))
  422.          {
  423.             /* window is not active, should we try to activate it? */
  424.             
  425.             lock = LockIBase(0);
  426.             IB_ActiveWindow = IntuitionBase->ActiveWindow;
  427.             UnlockIBase(lock);
  428.             
  429.             if (!IB_ActiveWindow ||
  430.                 !(IB_ActiveWindow->Flags & WFLG_MENUSTATE) && /* not showing menus */
  431.                 !(why == KEY && StrGadgetActive (IB_ActiveWindow))) /* no str gad active */
  432.             {
  433.                
  434.                /* do autopop? */
  435.                if (why == AUTO && autopop)
  436.                   PopToFront (win);
  437.                
  438.                if (why == KEY)
  439.                   ActivateWindow (win); /* need this to avoid losing keys */
  440.                else
  441.                   WACT (win); /* ...activate window */
  442.                
  443.                RememberActiveWindow(win);
  444.                
  445.             }
  446.          }
  447.       }
  448.       else
  449.       {
  450.          lock = LockIBase(0);
  451.          IB_ActiveWindow = IntuitionBase->ActiveWindow; 
  452.          UnlockIBase(lock);
  453.          
  454.          if (scractivate && mousescr && mousescr->FirstWindow &&
  455.              ((why == SCREEN) || 
  456.               (why == RMBACT && IB_ActiveWindow && IB_ActiveWindow->WScreen != mousescr)))
  457.          {
  458.             WACT (mousescr->FirstWindow); /* ...activate window */
  459.             RememberActiveWindow(mousescr->FirstWindow);
  460.          }
  461.       }
  462.    }
  463. }
  464.  
  465.  
  466. #define ALL_BUTTONS     (IEQUALIFIER_LEFTBUTTON|IEQUALIFIER_RBUTTON|IEQUALIFIER_MIDBUTTON)
  467. #define KEY_QUAL        (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT \
  468.                          |IEQUALIFIER_CONTROL \
  469.                          |IEQUALIFIER_LALT|IEQUALIFIER_RALT \
  470.                          |IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND)
  471. #define ALL_QUALS       (ALL_BUTTONS|KEY_QUAL)
  472.  
  473. #define REBLANKCOUNT    10      /* how long to wait to reblank mouse */
  474.  
  475. /*
  476.  * MainHandler is an input handler with no filter attached, it sees everything
  477.  * and so can manage keyactivation, autopointing, keyclicking and blanking
  478.  */
  479.  
  480.  
  481. SAVEDS void
  482.    MainHandler (CxMsg * CxMsg, CxObj * CO)
  483. {
  484.    static WORD apcount;         /* timer events since last mousemove */
  485.    struct InputEvent *ev;
  486.    
  487.    ev = (struct InputEvent *) CxMsgData (CxMsg);
  488.    
  489.    switch (ev->ie_Class)
  490.    {
  491.    case IECLASS_TIMER:          /*** AUTO-ACTIVATE/POP, SCREENBLANK, MOUSEBLANK ***/
  492.       
  493.       if (!(ev->ie_Qualifier & ALL_QUALS) && autopoint && !apcount--)
  494.       {
  495.          ActivateMouseWindow (AUTO);
  496.       }
  497.       
  498.       if (screenblank && !--blankcount) /* blank screen? */
  499.       {
  500.          /* Don't blank screen while we are still in the input.device processing */
  501.          /* Take care of screen mode promotors that open requesters */
  502.          Signal (YakTask, blankscreensigflag);
  503.          blankcount = blanktimeout; /* reset counter */
  504.       }                         /* in case screen opens on top */
  505.       
  506.       if (mouseblank && !--mblankcount) /* blank mouse? */
  507.       {
  508.          ForceTurnMouseOff ();
  509.          
  510.          /* in case someone else turns it on, reset counter */
  511.          mblankcount = mblanktimeout;
  512.       }
  513.       break;
  514.       
  515.    case IECLASS_RAWKEY:
  516.       if (!(ev->ie_Code & IECODE_UP_PREFIX))
  517.       {
  518.          if (click_volume && !(ev->ie_Qualifier & IEQUALIFIER_REPEAT))
  519.             Signal (YakTask, clicksigflag);
  520.          
  521.          if (!(ev->ie_Qualifier & ALL_BUTTONS) && keyactivate) /* perform key-activate */
  522.             ActivateMouseWindow (KEY);
  523.          
  524.          blankcount = blanktimeout; /* reset blanking countdown */
  525.  
  526.          UnBlankScreen();       /* turn off screen-blanking */
  527.          
  528.          if (mouseblank)
  529.          {
  530.             if (ev->ie_Qualifier & (IEQUALIFIER_LCOMMAND | IEQUALIFIER_RCOMMAND))
  531.             {
  532.                /* this allows use of keyboard to move mouse and to access menus */
  533.                mblankcount = mblanktimeout;  
  534.                
  535.                TurnMouseOn ();
  536.             }
  537.             else
  538.             {
  539.                if (blankmouseonkey)
  540.                {
  541.                   TurnMouseOff (); /* blank the mouse */
  542.                }
  543.             }
  544.          }
  545.          else
  546.          {
  547.             TurnMouseOn ();
  548.          }
  549.  
  550.          if ( (ev->ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) &&
  551.              (ev->ie_Qualifier & IEQUALIFIER_CAPSLOCK) &&
  552.              capshift )
  553.             CapShiftFunction(ev);
  554.       }
  555.       break;
  556.       
  557.    case IECLASS_RAWMOUSE:
  558.       /* restore screen/mouse pointer */
  559.       blankcount = blanktimeout; /* reset blanking countdowns */
  560.       mblankcount = mblanktimeout;
  561.  
  562.       UnBlankScreenAndMouse();          /* turn off screen-blanking */  
  563.  
  564.       /* maybe should check for depth gadgets? nah... */
  565.       if (!(ev->ie_Qualifier & KEY_QUAL))
  566.       {
  567.          if (!(ev->ie_Qualifier & ALL_BUTTONS))
  568.          {
  569.             apcount = autopoint_delay; /* reset auto-activate count */
  570.          }
  571.          else
  572.          {
  573.             misspop = TRUE;
  574.             apcount = -1;       /* button - wait for move */
  575.             
  576.             if ((rmbactivate && (ev->ie_Code == IECODE_RBUTTON)) || 
  577.                 (mmbactivate && (ev->ie_Code == IECODE_MBUTTON)))
  578.             {
  579.                ActivateMouseWindow (RMBACT);
  580.             }
  581.             
  582.             if (ev->ie_Code == IECODE_LBUTTON)
  583.             {
  584.                struct Window *win = WindowUnderMouse();
  585.                if (win == NULL)
  586.                {
  587.                   /* Check for screen depth gadget */
  588.                   
  589.                   struct Screen *screen = ScreenUnderMouse();
  590.                   struct Gadget *ScreenGadget = screen->FirstGadget;
  591.                   struct Gadget *DepthGadget = NULL;
  592.                   
  593.                   while (ScreenGadget != NULL)
  594.                   {
  595.                      if ((ScreenGadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_SDEPTH)
  596.                      {
  597.                         /* We found the screen depth gadget */
  598.                         DepthGadget = ScreenGadget;
  599.                      }
  600.                      ScreenGadget = ScreenGadget->NextGadget;
  601.                   }
  602.                   
  603.                   if ((DepthGadget != NULL) &&
  604.                       (screen->MouseY < DepthGadget->Height) &&
  605.                       (screen->MouseX > (screen->Width - DepthGadget->Width)))
  606.                   {
  607.                      /* Discard event, we'll do the processing ourselves */
  608.                      ev->ie_Class = IECLASS_NULL;
  609.                      
  610.                      /* Call main task to process it */
  611.                      Signal (YakTask, depthscreensigflag);
  612.                   }
  613.                }
  614.                else
  615.                {
  616.                   /* A new window will get activated, so remember it 
  617.                    * only if it is a non backdrop window
  618.                    */
  619.                   if (!(win->Flags & WFLG_BACKDROP))
  620.                   {
  621.                      RememberActiveWindow(win);
  622.                   }
  623.                }
  624.             }
  625.          }
  626.          
  627.       }
  628.       break;
  629.       
  630.    case IECLASS_DISKINSERTED:
  631.       blankcount = blanktimeout; /* reset blanking countdown */
  632.       UnBlankScreenAndMouse();          /* turn off screen-blanking */
  633.       break;
  634.       
  635.    }
  636. }
  637.  
  638.  
  639.  
  640. IMPORT ULONG secs, micros;
  641. IMPORT UBYTE FRONT_DELAY, BACK_DELAY;
  642.  
  643. void
  644.    WindowToFrontHandler (void)
  645. {
  646.    struct Window *win; 
  647.    static ULONG lastfrontmicros = 0l;
  648.    static ULONG lastfrontsecs = 0l;
  649.    static UBYTE frontclicks = 0;
  650.    
  651.    if (Window_To_Front.RequiredClicks >1)
  652.    {
  653.       if (DoubleClick(lastfrontsecs, lastfrontmicros, secs, micros))
  654.       {
  655.          frontclicks++;
  656.       }
  657.       else
  658.       {
  659.          frontclicks = 1;
  660.       }
  661.       lastfrontmicros = micros;
  662.       lastfrontsecs =  secs;
  663.    }
  664.    else
  665.    {
  666.       frontclicks = 1;
  667.    }
  668.    
  669.    if (frontclicks == Window_To_Front.RequiredClicks) 
  670.    {
  671.       if (win = WindowUnderMouse())
  672.       { 
  673.          mousescr = win->WScreen;
  674.          
  675.          if (IsIncludedScreen (mousescr, Window_To_Front))
  676.          {
  677.             if (OkayToPop (win) && 
  678.                 (!(Window_To_Front.Options & Opt_ExcludeWbWindow) || IsNotWbWindow (win)))
  679.                
  680.             {
  681.                if (win->Flags & WFLG_WBENCHWINDOW)
  682.                { 
  683.                   /* Let some time for wb processing, otherwise 
  684.                    * there will be a big delay of 1 second or so
  685.                    */
  686.                   Delay(FRONT_DELAY); 
  687.                }
  688.                WindowToFront (win); 
  689.             }
  690.             else 
  691.             {
  692.                if (Window_To_Front.Options & Opt_ScreenToFront)
  693.                {   
  694.                   ScreenToFront (mousescr);
  695.                   ActivateMouseWindow (SCREEN);
  696.                }
  697.             }
  698.          }
  699.       }
  700.       else 
  701.       {
  702.          mousescr = ScreenUnderMouse();
  703.          if ((IsIncludedScreen ( mousescr, Window_To_Front )) && 
  704.              (Window_To_Front.Options & Opt_ScreenToFront))
  705.          {
  706.             MyScreenToFront(mousescr);
  707.          }
  708.       }
  709.       
  710.       frontclicks = 0;
  711.    }
  712. }
  713.  
  714.  
  715. void
  716.    WindowToBackHandler (void)
  717. {
  718.    struct Window *win; 
  719.    static ULONG lastbackmicros = 0l;
  720.    static ULONG lastbacksecs = 0l;
  721.    static UBYTE backclicks = 0;
  722.    
  723.    if (Window_To_Back.RequiredClicks >1)
  724.    {
  725.       if (DoubleClick(lastbacksecs, lastbackmicros, secs, micros))
  726.       {
  727.          backclicks++;
  728.       }
  729.       else
  730.       {
  731.          backclicks = 1;
  732.       }
  733.       lastbackmicros = micros;
  734.       lastbacksecs =  secs;
  735.    }
  736.    else
  737.    {
  738.       backclicks = 1;
  739.    }
  740.    
  741.    if (backclicks == Window_To_Back.RequiredClicks) 
  742.    {
  743.       if (win = WindowUnderMouse())
  744.       {
  745.          mousescr = win->WScreen;
  746.          if (IsIncludedScreen ( mousescr, Window_To_Back ))
  747.          {
  748.             if (!(win->Flags & WFLG_BACKDROP) && 
  749.                 (win->NextWindow || (win->WScreen->FirstWindow != win)))
  750.             {
  751.                if (win->Flags & WFLG_WBENCHWINDOW)
  752.                { 
  753.                   /* Let some time for wb processing, otherwise 
  754.                    * there will be a big delay of 1 second or so
  755.                    */
  756.                   Delay(BACK_DELAY); 
  757.                }
  758.                WindowToBack(win); 
  759.             }
  760.             else 
  761.             {
  762.                if (Window_To_Back.Options & Opt_ScreenToBack)
  763.                {
  764.                   ScreenToBack (mousescr);
  765.                   ActivateMouseWindow (SCREEN);
  766.                }
  767.             }
  768.          }       
  769.       }
  770.       else 
  771.       {
  772.          mousescr = ScreenUnderMouse();
  773.          if ((IsIncludedScreen ( mousescr, Window_To_Back )) &&
  774.              (Window_To_Back.Options & Opt_ScreenToBack))
  775.          {
  776.             MyScreenToBack(mousescr);
  777.          }
  778.       }
  779.       backclicks = 0;
  780.    }
  781. }
  782.  
  783. void
  784.    ScreenCyclingHandler (void)
  785. {
  786.    static ULONG lastcyclingmicros = 0l;
  787.    static ULONG lastcyclingsecs = 0l;
  788.    static UBYTE cyclingclicks = 0;
  789.    
  790.    if (ScreenCycling.RequiredClicks >1)
  791.    {
  792.       if (DoubleClick(lastcyclingsecs, lastcyclingmicros, secs, micros))
  793.       {
  794.          cyclingclicks++;
  795.       }
  796.       else
  797.       {
  798.          cyclingclicks = 1;
  799.       }
  800.       lastcyclingmicros = micros;
  801.       lastcyclingsecs =  secs;
  802.    }
  803.    else
  804.    {
  805.       cyclingclicks = 1;
  806.    }
  807.    
  808.    if (cyclingclicks == ScreenCycling.RequiredClicks) 
  809.    {
  810.       mousescr = ScreenUnderMouse();
  811.       if (IsIncludedScreen ( mousescr, ScreenCycling ))
  812.       {
  813.          /* ev->ie_Class = IECLASS_NULL; */
  814.          MyScreenToBack (mousescr);
  815.       }
  816.       cyclingclicks = 0;
  817.    }
  818. }
  819.  
  820.  
  821.  
  822. /* close resources allocated for MainHandler */
  823. void
  824.    EndMainHandler ()
  825. {
  826.    /* DeleteCxObjAll works even with CxObj is NULL */
  827.    
  828.    DeleteCxObjAll(clickobj);    
  829.    
  830.    FreeAudio ();
  831.    if (intuiopsigbit != -1)
  832.       FreeSignal (intuiopsigbit);
  833.    if (clicksigbit != -1)
  834.       FreeSignal (clicksigbit);
  835.    if (depthscreensigbit != -1)
  836.       FreeSignal (depthscreensigbit);
  837.    if (blankscreensigbit != -1)
  838.       FreeSignal (blankscreensigbit);
  839.    UnBlankScreenAndMouse ();
  840. }
  841.  
  842.  
  843. /* open resources needed for MainHandler */
  844. BOOL
  845.    InitMainHandler ()
  846. {
  847.    if (((clicksigbit = AllocSignal (-1)) != -1) &&
  848.        ((intuiopsigbit = AllocSignal (-1)) != -1) &&
  849.        ((blankscreensigbit = AllocSignal (-1)) != -1) &&
  850.        ((depthscreensigbit = AllocSignal (-1)) != -1) &&
  851.        AllocAudio ())
  852.    {
  853.       YakTask = FindTask(NULL);
  854.       
  855.       clicksigflag       = 1 << clicksigbit;
  856.       intuiopsigflag     = 1 << intuiopsigbit;
  857.       blankscreensigflag = 1 << blankscreensigbit;
  858.       depthscreensigflag = 1 << depthscreensigbit;
  859.       
  860.       clickobj = CxCustom (MainHandler, 0L);
  861.       AttachCxObj (broker, clickobj);
  862.       
  863.       return TRUE;
  864.    }
  865.    EndMainHandler ();
  866.    return FALSE;
  867. }
  868.  
  869.  
  870. #endif
  871.  
  872.  
  873. #if !defined(CONV)
  874.  
  875. /* open/close resources needed for one of the MouseCycling handlers */
  876.  
  877. static VOID
  878.    ToggleYakHandler (YakHandler *YH)
  879. {
  880.    static IX tmpIX = {IX_VERSION,0, 0, 0, 0, 0, 0 }; /* declaring it as static saves some
  881.                                                       * bytes for the intitalization code 
  882.                                                       */
  883.    
  884.    /* DeleteCxObjAll() works even with NULL argument */
  885.    DeleteCxObjAll(YH->CxObj);    
  886.    YH->CxObj=NULL;
  887.    
  888.    if (YH->State == YKHK_ACTIVE) 
  889.    {
  890. #ifdef PREFS
  891.       if ((YH->CxObj = CxFilter(NULL)) && !CompatibleParseIX(YH->KeyDef, &tmpIX))
  892.       {
  893.          /* For prefs we don't want to really set up a filter */
  894.          DeleteCxObj(YH->CxObj); 
  895.          YH->CxObj=NULL;
  896.       }
  897.       else 
  898.          PostError("%s:\n\"%s\"", getString(Invalid_hotkey_specif_ERR), YH->KeyDef);
  899. #else
  900.       if ((YH->CxObj = CxFilter(NULL)) && !CompatibleParseIX(YH->KeyDef, &tmpIX))
  901.       {
  902.          CxObj *tmp_obj;
  903.          
  904.          SetFilterIX(YH->CxObj, &tmpIX);
  905.          AttachCxObj(broker, YH->CxObj);
  906.          
  907.          if (tmp_obj = CxSender(broker_mp, YH->Event))
  908.          {
  909.             AttachCxObj(YH->CxObj, tmp_obj);
  910.             if ((tmp_obj=CxTranslate(NULL)) && (tmpIX.ix_Code == IECODE_RBUTTON))
  911.                AttachCxObj(YH->CxObj, tmp_obj);
  912.          }
  913.       }
  914. #endif
  915.    }
  916. }
  917.  
  918.  
  919. /* open/close resources needed for Mouse Cycling */
  920. VOID
  921.    ToggleMouseCycling(VOID)
  922.    UBYTE i;
  923.    
  924.    InitMouseCyclingPatterns();
  925.    
  926.    for (i=0; i< NUM_HANDLERS ; i++)
  927.    {
  928.       ToggleYakHandler(&MouseCyclingHandlers[i]);
  929.    }
  930. }
  931.  
  932.  
  933. #endif
  934.